//@version=6
indicator("SulLaLuna — HTF M2 x Ultimate BB (Fusion)", shorttitle="M2xUBB ⚡", overlay=true, max_lines_count=500, max_labels_count=500, dynamic_requests=true)

// ==========================
// 🔧 Core Inputs
// ==========================
// HTF is fixed to Daily by design (user request). We allow smoothing via 5m base with default length 48.
htfTF          = input.timeframe("D", "HTF (locked)")
useSmoothHTF   = input.bool(true, "Smooth HTF using LTF base? (God Mode)")
smoothBaseTF   = input.timeframe("5", "Smoothing Base TF (LTF)")
smoothLength   = input.int(48, "Hull Smoothing Length (bars)", minval=10, tooltip="Default 48 (5m*48 ≈ 4H proxy). For Daily smooth, try 288.")

// Visuals
showBG         = input.bool(true,  "Paint M2 slope background on chart TF")
bgBull         = input.color(color.lime,  "BG Bull")
bgBear         = input.color(color.red,   "BG Bear")
bgNeutral      = input.color(color.gray,  "BG Neutral")
bgOpacity      = input.int(90, "BG Opacity", minval=0, maxval=100)

showHTFHull    = input.bool(true,  "Show HTF M2 Hull")
htfWidth       = input.int(2, "HTF Line Width")
htfColorBull   = input.color(color.lime, "HTF Bull Color")
htfColorBear   = input.color(color.red,  "HTF Bear Color")
htfColorFlat   = input.color(color.gray, "HTF Flat Color")

// Ultimate-style Bollinger on HTF Hull
bbGroup        = "Ultimate BB on HTF M2 Hull"
ubb_maType     = input.string("SMA",  "BB MA Type", options=["SMA","EMA","WMA","RMA"], group=bbGroup)
ubb_len        = input.int(20,        "BB Basis Length", group=bbGroup)
ubb_innerMult  = input.float(2.1,     "Inner Mult", step=0.1, group=bbGroup)
ubb_outerMult  = input.float(2.4,     "Outer Mult", step=0.1, group=bbGroup)
showBBFill     = input.bool(true,     "Show BB Fill", group=bbGroup)
fillTransp     = input.int(70,        "Fill Transparency", minval=0, maxval=100, group=bbGroup)

// Pivot & Divergence style (pivots used for entries/alerts)
pivGroup       = "HTF Hull Pivots & Entries"
pivotLen       = input.int(5, "Pivot Lookback", minval=1, group=pivGroup)
showPivots     = input.bool(true, "Show Pivot Labels", group=pivGroup)

// Alert toggles
alGroup        = "Alerts"
alertPivots    = input.bool(true,  "Alert on HTF Hull pivots (HIGH/LOW)", group=alGroup)
alertOverExt   = input.bool(true,  "Alert on Over-Extension (outside outer BB)", group=alGroup)
alertRevert    = input.bool(true,  "Alert on Reversion (re-enter from outside)", group=alGroup)

// ==========================
// 📦 Utility MAs
// ==========================
MA(src, len, kind) =>
    switch kind
        "SMA" => ta.sma(src, len)
        "EMA" => ta.ema(src, len)
        "WMA" => ta.wma(src, len)
        => ta.rma(src, len)

// Hull MA
hma(src, len) => ta.wma(2*ta.wma(src, len/2) - ta.wma(src, len), math.round(math.sqrt(len)))

// ==========================
// 🌊 Global M2 (FX-adjusted sum) scaled to symbol price
// ==========================
getM2() =>
    request.security("ECONOMICS:EUM2*FX:EURUSD", "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:USM2",               "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:CAM2*FX_IDC:CADUSD", "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:CHM2*FX_IDC:CHFUSD", "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:GBM2*FX:GBPUSD",     "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:FIM2/FX_IDC:USDFIM", "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:RUM2*FX_IDC:RUBUSD", "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:NZM2*FX_IDC:NZDUSD", "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:CNM2*FX_IDC:CNYUSD", "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:TWM2*FX_IDC:TWDUSD", "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:HKM2*FX_IDC:HKDUSD", "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:INM2*FX_IDC:INRUSD", "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:JPM2*FX_IDC:JPYUSD", "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:PHM2*FX_IDC:PHPUSD", "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:SGM2*FX_IDC:SGDUSD", "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:BRM2*FX_IDC:BRLUSD", "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:COM2*FX_IDC:COPUSD", "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:MXM2*FX_IDC:MXNUSD", "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:AEM2*FX_IDC:AEDUSD", "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:TRM2*FX_IDC:TRYUSD", "D", close, lookahead=barmerge.lookahead_on) +    request.security("ECONOMICS:ZAM2*FX_IDC:ZARUSD", "D", close, lookahead=barmerge.lookahead_on)
var float _m2_cache = na
_m2 = nz(_m2_cache[0])
_m2 := getM2()
scaleFactor = close / ta.highest(_m2, 500)
scaledM2    = _m2 * scaleFactor

// ==========================
// 🧭 Chart-TF M2 Hull (for BG confluence only)
// ==========================
chartHull = hma(scaledM2, 55)
up   = chartHull > chartHull[1]
down = chartHull < chartHull[1]
colBG = up ? color.new(bgBull, bgOpacity) : down ? color.new(bgBear, bgOpacity) : color.new(bgNeutral, bgOpacity)
bgcolor(showBG ? colBG : na)

// ==========================
// 📈 HTF (Daily) M2 Hull — smoothed via LTF base (default 5m x 48)
// ==========================
var float htfHull = na
var float htfHullPrev = na
if useSmoothHTF
    // Smooth proxy built from LTF candles for responsiveness
    htfHull      := request.security(syminfo.tickerid, smoothBaseTF, hma(scaledM2, smoothLength))
    htfHullPrev  := request.security(syminfo.tickerid, smoothBaseTF, hma(scaledM2, smoothLength)[1])
else
    // Classic daily hull
    htfHull      := request.security(syminfo.tickerid, htfTF, hma(scaledM2, 55))
    htfHullPrev  := request.security(syminfo.tickerid, htfTF, hma(scaledM2, 55)[1])

htfBull = htfHull > htfHullPrev
htfBear = htfHull < htfHullPrev
htfLineColor = htfBull ? htfColorBull : htfBear ? htfColorBear : htfColorFlat
plot(showHTFHull ? htfHull : na, "HTF M2 Hull", color=htfLineColor, linewidth=htfWidth)

// ==========================
// 🧠 Ultimate-style BB applied to HTF M2 Hull
// ==========================
ubb_basis = MA(htfHull, ubb_len, ubb_maType)
ubb_dev   = ta.stdev(htfHull, ubb_len)
ubb_up_i  = ubb_basis + ubb_innerMult * ubb_dev
ubb_dn_i  = ubb_basis - ubb_innerMult * ubb_dev
ubb_up_o  = ubb_basis + ubb_outerMult * ubb_dev
ubb_dn_o  = ubb_basis - ubb_outerMult * ubb_dev

// Invisible lines for fills
U1 = plot(ubb_up_i,  color=na)
L1 = plot(ubb_dn_i,  color=na)
U2 = plot(ubb_up_o,  color=na)
L2 = plot(ubb_dn_o,  color=na)
fill(U1, U2, color=showBBFill ? color.new(color.green, fillTransp) : na, title="Upper BB Fill")
fill(L1, L2, color=showBBFill ? color.new(color.red,   fillTransp) : na, title="Lower BB Fill")
plot(ubb_basis,  "HTF BB Basis", color=color.orange)

// ==========================
// 🎯 Pivots on HTF Hull (ideal entries)
// ==========================
ph = ta.pivothigh(htfHull, pivotLen, pivotLen)
pl = ta.pivotlow(htfHull,  pivotLen, pivotLen)

if showPivots and not na(pl)
    label.new(bar_index[pivotLen], pl, text="HTF PIVOT LOW", style=label.style_label_up, color=color.new(color.lime, 0), textcolor=color.black, yloc=yloc.belowbar)
if showPivots and not na(ph)
    label.new(bar_index[pivotLen], ph, text="HTF PIVOT HIGH", style=label.style_label_down, color=color.new(color.red, 0), textcolor=color.white, yloc=yloc.abovebar)

// ==========================
// 🚦 Over-Extension / Reversion Logic (on HTF Hull vs outer BB)
// ==========================
// Outside outer bands
overbuy  = ta.crossover(htfHull, ubb_up_o) or (htfHull > ubb_up_o and htfHull[1] <= ubb_up_o[1])
oversell = ta.crossunder(htfHull, ubb_dn_o) or (htfHull < ubb_dn_o and htfHull[1] >= ubb_dn_o[1])
// Re-enter after outside
reenterDown = ta.crossunder(htfHull, ubb_up_o)   // from above back inside
reenterUp   = ta.crossover(htfHull, ubb_dn_o)    // from below back inside

plotshape(overbuy,  title="Overbuy (HTF Hull > outer)",  style=shape.triangledown, color=color.fuchsia, location=location.abovebar, size=size.tiny)
plotshape(oversell, title="Oversell (HTF Hull < outer)", style=shape.triangleup,   color=color.orange,  location=location.belowbar, size=size.tiny)
plotshape(reenterDown, title="Re-enter from Overbuy", style=shape.circle, color=color.red,   location=location.abovebar, size=size.tiny)
plotshape(reenterUp,   title="Re-enter from Oversell",style=shape.circle, color=color.lime,  location=location.belowbar, size=size.tiny)

// ==========================
// 📣 Alerts
// ==========================
// Pivot alerts (confirmed at pivot bar, hence use series ph/pl which prints pivotLen bars late)
alertcondition(alertPivots and not na(pl), title="HTF M2 Hull Pivot LOW",  message="🌕 SulLaLuna: HTF M2 Hull PIVOT LOW — consider LONG setups / scale-in with confluence.")
alertcondition(alertPivots and not na(ph), title="HTF M2 Hull Pivot HIGH", message="🌕 SulLaLuna: HTF M2 Hull PIVOT HIGH — consider SHORT/trim or hedge.")

// Over-extension & reversion
alertcondition(alertOverExt and overbuy,    title="HTF Hull Over-Extension (Overbought)", message="🟣 HTF M2 Hull outside UPPER outer BB → watch for fade/reversion.")
alertcondition(alertOverExt and oversell,   title="HTF Hull Over-Extension (Oversold)",  message="🟠 HTF M2 Hull outside LOWER outer BB → watch for bounce/reversion.")
alertcondition(alertRevert  and reenterDown, title="HTF Hull Re-Entry from Overbought", message="🔻 HTF M2 Hull re-entered from ABOVE outer BB → short bias / mean reversion.")
alertcondition(alertRevert  and reenterUp,   title="HTF Hull Re-Entry from Oversold",   message="🚀 HTF M2 Hull re-entered from BELOW outer BB → long bias / mean reversion.")

// ==========================
// 📝 Notes
// - Use on intraday charts (e.g., 1–15m). BG reflects chart-TF M2 slope for confluence.
// - Trading decisions: Prefer entries near HTF pivot labels especially when they occur after over-extension + re-entry.
// - Risk controls: size down when HTF Hull is flat (gray line color). Always pre-define SL/TP using ATR/structure.
